package com.share.finance.asset.sjd.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONPath;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.share.common.utils.GroovyUtil;
import com.share.finance.asset.sjd.mapper.FieldConfMapper;
import com.share.finance.asset.sjd.model.db.FieldConf;
import com.share.finance.asset.sjd.service.IFieldConfService;
import groovy.lang.GroovyObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author author
 * @since 2023-11-30
 */
@Slf4j
@Service
public class FieldConfServiceImpl extends ServiceImpl<FieldConfMapper, FieldConf> implements IFieldConfService {
    final private String DEFAULT_PRODUCT_CODE = "default";
    @Resource
    private FieldConfMapper fieldConfMapper;
    private List<FieldConf> defaultProductCodeList = new LinkedList<>();
    private Map<String, List<FieldConf>> productCodeEventMap = new HashMap<>();
    private Map<String, GroovyObject> groovyObjectMap = new HashMap<>();

    @Override
    public Object initFieldConf() {
        Map<String, List<FieldConf>> productCodeEventMap_ = new HashMap<>();
        Map<String, GroovyObject> groovyObjectMap_ = new HashMap<>();
        LambdaQueryWrapper<FieldConf> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FieldConf::getIsValid, "1");
        List<FieldConf> confList = fieldConfMapper.selectList(wrapper);
        defaultProductCodeList = confList.stream().filter(e -> DEFAULT_PRODUCT_CODE.equals(e.getProductCode())).collect(Collectors.toList());
        for (FieldConf item : confList) {
            //0.排除默认
            String productCode = item.getProductCode();
            String eventType = item.getEventType();
            if (DEFAULT_PRODUCT_CODE.equals(productCode)) {
                continue;
            }

            //1.kv值初始化
            String key = productCode + "-" + eventType;
            List<FieldConf> tmpList = productCodeEventMap_.get(key);
            if (tmpList == null) {
                tmpList = defaultProductCodeList.stream().filter(
                        e -> StringUtils.isBlank(e.getEventType()) || e.getEventType().equals(eventType)).collect(Collectors.toList());
                productCodeEventMap_.put(key, tmpList);
            }
            tmpList.add(item);

            //groovy脚本初始化
            if ("0".equals(item.getValueWay())) {
                String key2 = productCode + "-" + eventType + "-" + item.getFieldName();
                try {
                    groovyObjectMap_.put(key2, GroovyUtil.createGroovyObject(item.getGroovy()));
                } catch (Exception e) {
                    log.error("groovy脚本初始化异常,item={}", JSON.toJSONString(item), e);
                    throw new RuntimeException("groovy脚本初始化异常,groovy=" + item.getGroovy());
                }
            }
        }
        if (productCodeEventMap_ != null) {
            productCodeEventMap = productCodeEventMap_;
        }

        if (groovyObjectMap_ != null) {
            groovyObjectMap = groovyObjectMap_;
        }
        return confList;
    }

    @Override
    public Object exeGroovyScript(String jsonReqStr, FieldConf item) {
        try {
            String key = item.getProductCode() + "-" + item.getEventType() + "-" + item.getFieldName();
            return groovyObjectMap.get(key).invokeMethod("parseJson", jsonReqStr);
        } catch (Exception e) {
            return null;
        }
    }

    @Override
    public List<FieldConf> listFieldConf(String productCode, String eventType) {
        List<FieldConf> fieldConfs = productCodeEventMap.get(productCode + "-" + eventType);
        if (CollectionUtils.isEmpty(fieldConfs)) {
            //事件不配置,一条都不配置,使用默认的
            fieldConfs = defaultProductCodeList.stream().filter(
                    e -> StringUtils.isBlank(e.getEventType()) || e.getEventType().equals(eventType)).collect(Collectors.toList());
        }
        return fieldConfs;
    }

    //计算默认字段的值
    @Override
    public Map<String, Object> calcDefultParam(String jsonReqStr, String productCode, String eventType) {
        Map<String, Object> defaultParam = new HashMap<>();
        List<FieldConf> fieldConfs = listFieldConf(productCode, eventType);
        if (!CollectionUtils.isEmpty(fieldConfs)) {
            for (FieldConf item : fieldConfs) {
                try {
                    Object vaule = null;
                    if ("1".equals(item.getValueWay())) {
                        vaule = JSONPath.read(jsonReqStr, item.getJsonPath());
                    } else if ("0".equals(item.getValueWay())) {
                        vaule = exeGroovyScript(jsonReqStr, item);
                    }
                    defaultParam.put(item.getFieldName(), vaule);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return defaultParam;
    }
}
